home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / gsdb21.arc / GS_KEYI.PAS < prev    next >
Pascal/Delphi Source File  |  1991-01-04  |  23KB  |  511 lines

  1. {
  2.                            Keyboard Input Routines
  3.  
  4.        GS_KeyI Copyright (c)  Richard F. Griffin
  5.  
  6.         9 April 1990
  7.  
  8.        102 Molded Stone Pl
  9.        Warner Robins, GA  31088
  10.  
  11.        -------------------------------------------------------------
  12.        This unit handles the objects for all keyboard data entry
  13.        operations.
  14.  
  15.  
  16.        The following example shows how this unit may be used in conjunction
  17.        with the GS_DB_FL unit to create a screen menu.  The AcceptField
  18.        method actually calls the EditString method and stores the result.
  19.        The programmer can handle the cursor commands to move around the
  20.        different fields in the following way.  Note that Escape allows an
  21.        abort of the procedure, while Ctrl-End is the normal way to exit:
  22.  
  23.  
  24.    procedure HlthData_Objct.Accept;
  25.    var
  26.       fpos : integer;
  27.       fini : boolean;
  28.    begin
  29.       fpos := 1;
  30.       fini := false;
  31.       while not fini do
  32.       begin
  33.          case fpos of
  34.            1 : F_CODE.PutField(F_CODE.AcceptField(1,1,'    F_CODE:  '));
  35.            2 : L_NAME.PutField(L_NAME.AcceptField(1,2,'    L_NAME:  '));
  36.            3 : M_DATE.PutField(M_DATE.AcceptField(1,3,'    M_DATE:  '));
  37.          end;
  38.          case GS_KeyI_Chr of
  39.             Kbd_RTb,
  40.             Kbd_UpAr  :  if fpos > 1 then dec(fpos);
  41.             Kbd_CEnd  :  fini := true;
  42.             Kbd_CHom  :  fpos := 1;
  43.             else inc(fpos);
  44.          end;
  45.          if fpos > 3 then fpos := 1;
  46.          if (GS_KeyI_Esc) or (fini) then exit;
  47.       end;
  48.    end;
  49.  
  50.  
  51. }
  52. {.pa}
  53. {
  54.  
  55.  
  56.                             ┌─────────────────────┐
  57.                             │  INTERFACE SECTION  │
  58.                             └─────────────────────┘
  59. }
  60.  
  61. unit GS_KeyI;
  62. interface
  63. uses
  64.    CRT, DOS, GS_Scrn;
  65.  
  66. const
  67.    BeepTime = 200;
  68.    BeepFreq = 600;
  69.  
  70.    Kbd_Null = #0;                     {Null Character}
  71.    Kbd_Nul  = #3;                     {Another Null}
  72.    Kbd_Bsp  = #8;                     {Backspace}
  73.    Kbd_Tab  = #9;                     {Tab}
  74.    Kbd_Ret  = #13;                    {Return}
  75.    Kbd_RTb  = #15;                    {Shift-Tab}
  76.    Kbd_AlQ  = #16;                    {Alt-Q}
  77.    Kbd_AlW  = #17;                    {Alt-W}
  78.    Kbd_AlE  = #18;                    {Alt-E}
  79.    Kbd_AlR  = #19;                    {Alt-R}
  80.    Kbd_AlT  = #20;                    {Alt-T}
  81.    Kbd_AlY  = #21;                    {Alt-Y}
  82.    Kbd_AlU  = #22;                    {Alt-U}
  83.    Kbd_AlI  = #23;                    {Alt-I}
  84.    Kbd_AlO  = #24;                    {Alt-O}
  85.    Kbd_AlP  = #25;                    {Alt-P}
  86.    Kbd_Esc  = #27;                    {Escape}
  87.    Kbd_AlA  = #30;                    {Alt-A}
  88.    Kbd_AlS  = #31;                    {Alt-S}
  89.    Kbd_AlD  = #32;                    {Alt-D}
  90.    Kbd_AlF  = #33;                    {Alt-F}
  91.    Kbd_AlG  = #34;                    {Alt-G}
  92.    Kbd_AlH  = #35;                    {Alt-H}
  93.    Kbd_AlJ  = #36;                    {Alt-J}
  94.    Kbd_AlK  = #37;                    {Alt-K}
  95.    Kbd_AlL  = #38;                    {Alt-L}
  96.    Kbd_AlZ  = #44;                    {Alt-Z}
  97.    Kbd_AlX  = #45;                    {Alt-X}
  98.    Kbd_AlC  = #46;                    {Alt-C}
  99.    Kbd_AlV  = #47;                    {Alt-V}
  100.    Kbd_AlB  = #48;                    {Alt-B}
  101.    Kbd_AlN  = #49;                    {Alt-N}
  102.    Kbd_AlM  = #50;                    {Alt-M}
  103.    Kbd_F1   = #59;                    {F1}
  104.    Kbd_F2   = #60;                    {F2}
  105.    Kbd_F3   = #61;                    {F3}
  106.    Kbd_F4   = #62;                    {F4}
  107.    Kbd_F5   = #63;                    {F5}
  108.    Kbd_F6   = #64;                    {F6}
  109.    Kbd_F7   = #65;                    {F7}
  110.    Kbd_F8   = #66;                    {F8}
  111.    Kbd_F9   = #67;                    {F9}
  112.    Kbd_F10  = #68;                    {F10}
  113.    Kbd_Home = #71;                    {Home}
  114.    Kbd_UpAr = #72;                    {Up Arrow}
  115.    Kbd_PgUp = #73;                    {Page Up}
  116.    Kbd_LfAr = #75;                    {Left Arrow}
  117.    Kbd_RtAr = #77;                    {Right Arrow}
  118.    Kbd_End  = #79;                    {End}
  119.    Kbd_DnAr = #80;                    {Down Arrow}
  120.    Kbd_PgDn = #81;                    {Page Down}
  121.    Kbd_Ins  = #82;                    {Insert}
  122.    Kbd_Del  = #83;                    {Delete}
  123.    Kbd_F11  = #84;                    {Shift-F1}
  124.    Kbd_F12  = #85;                    {Shift-F2}
  125.    Kbd_F13  = #86;                    {Shift-F3}
  126.    Kbd_F14  = #87;                    {Shift-F4}
  127.    Kbd_F15  = #88;                    {Shift-F5}
  128.    Kbd_F16  = #89;                    {Shift-F6}
  129.    Kbd_F17  = #90;                    {Shift-F7}
  130.    Kbd_F18  = #91;                    {Shift-F8}
  131.    Kbd_F19  = #92;                    {Shift-F9}
  132.    Kbd_F20  = #93;                    {Shift-F10}
  133.    Kbd_F21  = #94;                    {Ctrl-F1}
  134.    Kbd_F22  = #95;                    {Ctrl-F2}
  135.    Kbd_F23  = #96;                    {Ctrl-F3}
  136.    Kbd_F24  = #97;                    {Ctrl-F4}
  137.    Kbd_F25  = #98;                    {Ctrl-F5}
  138.    Kbd_F26  = #99;                    {Ctrl-F6}
  139.    Kbd_F27  = #100;                   {Ctrl-F7}
  140.    Kbd_F28  = #101;                   {Ctrl-F8}
  141.    Kbd_F29  = #102;                   {Ctrl-F9}
  142.    Kbd_F30  = #103;                   {Ctrl-F10}
  143.    Kbd_F31  = #104;                   {Alt-F1}
  144.    Kbd_F32  = #105;                   {Alt-F2}
  145.    Kbd_F33  = #106;                   {Alt-F3}
  146.    Kbd_F34  = #107;                   {Alt-F4}
  147.    Kbd_F35  = #108;                   {Alt-F5}
  148.    Kbd_F36  = #109;                   {Alt-F6}
  149.    Kbd_F37  = #110;                   {Alt-F7}
  150.    Kbd_F38  = #111;                   {Alt-F8}
  151.    Kbd_F39  = #112;                   {Alt-F9}
  152.    Kbd_F40  = #113;                   {Alt-F10}
  153.    Kbd_CPSc = #114;                   {Ctrl-PrtSc}
  154.    Kbd_CLAr = #115;                   {Ctrl-Left Arrow}
  155.    Kbd_CRAr = #116;                   {Ctrl-Right Arrow}
  156.    Kbd_CEnd = #117;                   {Ctrl-End}
  157.    Kbd_CPDn = #118;                   {Ctrl-Page Down}
  158.    Kbd_CHom = #119;                   {Ctrl-Home}
  159.    Kbd_Al1  = #120;                   {Alt-1}
  160.    Kbd_Al2  = #121;                   {Alt-2}
  161.    Kbd_Al3  = #122;                   {Alt-3}
  162.    Kbd_Al4  = #123;                   {Alt-4}
  163.    Kbd_Al5  = #124;                   {Alt-5}
  164.    Kbd_Al6  = #125;                   {Alt-6}
  165.    Kbd_Al7  = #126;                   {Alt-7}
  166.    Kbd_Al8  = #127;                   {Alt-8}
  167.    Kbd_Al9  = #128;                   {Alt-9}
  168.    Kbd_Al0  = #129;                   {Alt-0}
  169.    Kbd_AlHy = #130;                   {Alt-Hyphen}
  170.    Kbd_AlEq = #131;                   {Alt-Equal}
  171.    Kbd_CPUp = #132;                   {Ctrl-Page up}
  172.  
  173. type
  174.  
  175. {
  176.          ┌──────────────────────────────────────────────────────────┐
  177.          │  ********   Object for Keyboard Entry Action   *******   │
  178.          │                                                          │
  179.          │  This object type describes the structure for any child  │
  180.          │  so that the child object can use a virtual method to    │
  181.          │  handle processing of function keys.                     │
  182.          └──────────────────────────────────────────────────────────┘
  183. }
  184.  
  185.    GS_KeyI_Objt =  Object
  186.                       CPos        : Word;
  187.                                       {Holds the position within the string}
  188.                       Ch          : Char;
  189.                                       {Holds the last character read}
  190.                       First       : boolean;
  191.                                       {Flag to detect the first real character}
  192.                                       {entered from the keyboard}
  193.                       Modified    : boolean;
  194.                                       {Flag to signal whether the field was}
  195.                                       {mofified, or the default was returned}
  196.                       Wait_CR     : boolean;
  197.                                       {Flag to wait for Carriage Return before}
  198.                                       {exit.  If false, will exit when the}
  199.                                       {field is full}
  200.  
  201.                       constructor Init;
  202.                       function    EditString(T : string; x, y, l : integer)
  203.                                             : string;
  204.                       procedure Check_Func_Keys; virtual;
  205.                                       {Note this method is virtual, so it may}
  206.                                       {be replaced by any child method for its}
  207.                                       {own processing of function key actions}
  208.                    end;
  209.  
  210.  
  211. var
  212.    GS_KeyI_Esc,
  213.    GS_KeyI_Fuc,
  214.    GS_KeyI_Ins,
  215.    GS_KeyI_Ret   : boolean;
  216.    GS_KeyI_Chr   : char;
  217.    GS_KeyI_Str   : string[255];
  218.  
  219. Function GS_KeyI_GetKey : char;       {Any program can call this to read a}
  220.                                       {character and test for function keys}
  221. procedure WaitForKey;
  222. procedure SoundBell( t,h : word);
  223. implementation
  224.  
  225. procedure SoundBell( t,h : word);
  226. begin
  227.    Sound(h);
  228.    Delay(t);
  229.    NoSound;
  230. end;
  231.  
  232. procedure WaitForKey;
  233. var
  234.    c  : char;
  235. begin
  236.    c := GS_KeyI_GetKey;
  237. end;
  238. {.pa}
  239. {
  240.  
  241.                                GS_KEYI_GETKEY
  242.  
  243.      ╔══════════════════════════════════════════════════════════════════╗
  244.      ║                                                                  ║
  245.      ║   The GS_KeyI_GetKey function is used to read a character from   ║
  246.      ║   Keyboard.  It can be called from any program.                  ║
  247.      ║                                                                  ║
  248.      ║       Calling the Function:                                      ║
  249.      ║                                                                  ║
  250.      ║           Ch := GS_KeyI_GetKey                                   ║
  251.      ║                                                                  ║
  252.      ║               ( where Ch is of type char. )                      ║
  253.      ║                                                                  ║
  254.      ║       Result:                                                    ║
  255.      ║                                                                  ║
  256.      ║           A character is returned.  If it is a function key,     ║
  257.      ║           GS_KeyI_Func is set true.  The character is also       ║
  258.      ║           saved in GS_KeyI_Chr, a global variable (just in       ║
  259.      ║           case it is needed at a later date)                     ║
  260.      ║                                                                  ║
  261.      ╚══════════════════════════════════════════════════════════════════╝
  262.  
  263. }
  264.  
  265.  
  266. Function GS_KeyI_GetKey : char;
  267. var
  268.    ch: char;
  269. begin
  270.   Ch := ReadKey;                      {Use TP ReadKey Function}
  271.   If (Ch = #0) then                   {It must be a function key }
  272.   begin
  273.     Ch := ReadKey;                    {So read the function code}
  274.     GS_KeyI_Fuc := true;              {Set function flag}
  275.   end
  276.   else GS_KeyI_Fuc := false;
  277.   GS_KeyI_Chr := Ch;                  {Save in a global variable for general}
  278.                                       {principle.}
  279.   GS_KeyI_GetKey := Ch;               {Return character}
  280. end;
  281. {.pa}
  282. {
  283.  
  284.                                     INIT
  285.  
  286.      ╔══════════════════════════════════════════════════════════════════╗
  287.      ║                                                                  ║
  288.      ║   The INIT method initializes objectname by setting flags to     ║
  289.      ║   false.  More importantly, it links the virtual method table.   ║
  290.      ║                                                                  ║
  291.      ║       Calling the Method:                                        ║
  292.      ║                                                                  ║
  293.      ║           objectname.Init                                        ║
  294.      ║                                                                  ║
  295.      ║               ( where objectname is of type GS_KeyI_Objt )       ║
  296.      ║                                                                  ║
  297.      ║       Result:                                                    ║
  298.      ║                                                                  ║
  299.      ║           object is initialized.                                 ║
  300.      ║                                                                  ║
  301.      ╚══════════════════════════════════════════════════════════════════╝
  302.  
  303. }
  304.  
  305.  
  306. constructor GS_KeyI_Objt.Init;
  307. begin
  308.    Wait_CR := true;                   {Wait for Carriage Return on field edit}
  309. end;
  310. {.pa}
  311. {
  312.  
  313.                                  EDITSTRING
  314.  
  315.      ╔══════════════════════════════════════════════════════════════════╗
  316.      ║                                                                  ║
  317.      ║   The EDITSTRING method will allow onscreen editing of a data    ║
  318.      ║   string.  It allows use of cursor keys and tabs as well.        ║
  319.      ║                                                                  ║
  320.      ║       Calling the Method:                                        ║
  321.      ║                                                                  ║
  322.      ║           objectname.EditString(St,x,y,lgth)                     ║
  323.      ║                                                                  ║
  324.      ║               ( where objectname is of type GS_KeyI_Objt         ║
  325.      ║                       St is a string default value,              ║
  326.      ║                       x is the screen column position to start,  ║
  327.      ║                       y is the screen row position to start,     ║
  328.      ║                       lgth is the maximum field length )         ║
  329.      ║                                                                  ║
  330.      ║       Result:                                                    ║
  331.      ║                                                                  ║
  332.      ║           An edited string is returned.  If Escape is pressed,   ║
  333.      ║           the original default value is returned.                ║
  334.      ║                                                                  ║
  335.      ╚══════════════════════════════════════════════════════════════════╝
  336.  
  337. }
  338. {
  339.          ┌──────────────────────────────────────────────────────────┐
  340.          │  ********        Function Key Processor        *******   │
  341.          │                                                          │
  342.          │  This routine processes any function key that is pressed │
  343.          │  during edit mode.  If it is one ether insert is on or   │
  344.          │  off.  BIOS calls are used.                              │
  345.          └──────────────────────────────────────────────────────────┘
  346. }
  347.  
  348.  
  349. procedure GS_KeyI_Objt.Check_Func_Keys;
  350. begin
  351.    case Ch of
  352.             Kbd_Home  : CPos := 1;    {Home key sets cursor to start}
  353.             Kbd_End   : CPos := Succ(Length(GS_KeyI_Str));
  354.                                       {End key sets cursor to string length + 1}
  355.  
  356.             Kbd_Ins   : begin         {Insert Key switches insert flag}
  357.                            GS_KeyI_Ins := not GS_KeyI_Ins;
  358.                                       {Set insert flag to opposite}
  359.                            GS_Scrn_SetCursor(GS_KeyI_Ins);
  360.                                       {Go set cursor to line or large based on}
  361.                                       {insert flag true/false}
  362.                         end;
  363.             Kbd_LfAr  : if CPos > 1 then Dec(CPos);
  364.                                       {Left Arrow will backup cursor 1 position}
  365.             Kbd_RtAr  : if CPos <= Length(GS_KeyI_Str) then Inc(CPos);
  366.                                       {Right Arrow will advance cursor}
  367.             Kbd_Bsp   :               {Backspace will delete char to the left}
  368.                         if CPos > 1 then
  369.                         begin
  370.                            Delete(GS_KeyI_Str, Pred(CPos), 1);
  371.                            Dec(CPos);
  372.                         end;
  373.             Kbd_Del   :               {Delete will delete char at cursor}
  374.                         if CPos <= Length(GS_KeyI_Str) then
  375.                            Delete(GS_KeyI_Str, CPos, 1);
  376. {
  377.          ┌──────────────────────────────────────────────────────────┐
  378.          │  The following keys will simulate the Return key being   │
  379.          │  pressed.  The actual key pressed can be tested by the   │
  380.          │  calling program using the character in GS_KeyI_Chr,     │
  381.          │  using the Kbd_xxx constant values.                      │
  382.          └──────────────────────────────────────────────────────────┘
  383. }
  384.             Kbd_Tab,                  {Tab Key}
  385.             Kbd_Rtb,                  {Shift-Tab key}
  386.             Kbd_UpAr,                 {Up Arrow}
  387.             Kbd_DnAr,                 {Down Arrow}
  388.             Kbd_PgUp,                 {Page Up}
  389.             Kbd_PgDn,                 {Page Down}
  390.             Kbd_CEnd,                 {Ctrl-End}
  391.             Kbd_CHom,                 {Ctrl-Home}
  392.             Kbd_Ret   : begin         {Return}
  393.                            GS_KeyI_Ret := true;
  394.                                       {Set Return Flag true}
  395.                            Ch := Kbd_Ret;
  396.                         end;
  397.  
  398.  
  399.             Kbd_Esc   : begin         {Escape Key causes an exit with the}
  400.                                       {original default value returned}
  401.                            GS_KeyI_Str := '';
  402.                            GS_KeyI_Esc := True;
  403.                         end;
  404.    end;
  405. end;
  406. {
  407.          ┌──────────────────────────────────────────────────────────┐
  408.          │  ********        Edit String Procedure         *******   │
  409.          │                                                          │
  410.          │  This is the main method to edit an input string.  The   │
  411.          │  usual cursor keys are processed through a method that   │
  412.          │  may be replaced by a child object's virtual method.     │
  413.          │  The Escape key will terminate and return the default    │
  414.          │  value to the calling program.                           │
  415.          └──────────────────────────────────────────────────────────┘
  416. }
  417.  
  418.  
  419. function GS_KeyI_Objt.EditString(T : string; x, y, l : integer) : string;
  420. begin
  421.    GS_KeyI_Ins := True;               {Start in insert mode}
  422.    GS_KeyI_Esc := False;              {Set the Escape flag false}
  423.    GS_KeyI_Ret := false;              {Set Return flag false}
  424.    Modified := false;                 {Flag for field not modified}
  425.    First := True;                     {Flag set for no characters yet entered}
  426.    GS_KeyI_Str := T;                  {Store default value in work string}
  427.    GS_Scrn_SetCursor(GS_KeyI_Ins);    {Go set cursor size}
  428.    CPos := 1;                         {Set cursor position on line to start}
  429.    repeat
  430.       gotoxy(x,y);                    {Go to proper location on screen}
  431.       write(GS_KeyI_Str,'':l-length(GS_KeyI_Str));
  432.                                       {Display the work string}
  433.       GotoXY(CPos+x-1, y);            {Go to current position in the string}
  434.       Ch := GS_KeyI_GetKey;           {Get the next keyboard entry}
  435.       if (GS_KeyI_Fuc) or (Ch in [#0..#31]) then
  436.                                       {See if function key or control char}
  437.       begin
  438.          Check_Func_Keys;             {If it is, go process it.  Note this is}
  439.                                       {a virtual method that may go to a child}
  440.                                       {object's method}
  441.       end
  442.       else                            {Otherwise add character to the string}
  443.       begin
  444.  
  445. {
  446.               ┌─────────────────────────────────────────────┐
  447.               │  If this is the very first character to     │
  448.               │  be pressed, clear the work string first.   │
  449.               │  This allows editing of the work string     │
  450.               │  if cursor keys are used before a character │
  451.               │  is entered, or total replacement by        │
  452.               │  pressing a character key first.            │
  453.               └─────────────────────────────────────────────┘
  454. }
  455.  
  456.          if First then
  457.          begin
  458.             GS_KeyI_Str := '';
  459.          end;
  460. {
  461.               ┌─────────────────────────────────────────────┐
  462.               │  If insert is on then insert the character. │
  463.               │  Otherwise, if at the end of the string,    │
  464.               │  just add the new character.  If insert is  │
  465.               │  off and not at the end of the string,      │
  466.               │  replace the existing character.            │
  467.               └─────────────────────────────────────────────┘
  468. }
  469.          if (GS_KeyI_Ins) then Insert(Ch, GS_KeyI_Str, CPos)
  470.             else if CPos > Length(GS_KeyI_Str) then
  471.                GS_KeyI_Str := GS_KeyI_Str + Ch
  472.                   else GS_KeyI_Str[CPos] := Ch;
  473.  
  474.          Inc(CPos);                   {Step to the next location in the string}
  475.       end;
  476.       First := False;                 {Set first character flag to false}
  477.       if length(GS_KeyI_Str) > l then
  478.                                       {If string is longer than allowed}
  479.       begin
  480.          SoundBell(BeepTime,BeepFreq);
  481.          delete(GS_KeyI_Str,length(GS_KeyI_Str),1);
  482.                                       {Remove the last character in the string}
  483.          dec(CPos);                   {Back up one position}
  484.       end;
  485.       if (CPos > l) then
  486.          if (not Wait_CR) and (Ch <> Kbd_End) then
  487.          begin
  488.             Ch := Kbd_Ret;
  489.             GS_KeyI_Ret := true;      {If field is full and no need to wait}
  490.          end                          {for a carriage return, simulate one}
  491.          else CPos := l;
  492.    until (Ch = Kbd_Ret) or (Ch = Kbd_Esc);
  493.                                       {Continue until Return or Escape pressed}
  494.    GS_Scrn_SetCursor(False);          {Set cursor size to small cursor}
  495.    if T = GS_KeyI_Str then Modified := false else Modified := true;
  496.    if GS_KeyI_Esc then EditString := T else
  497.                        EditString := GS_KeyI_Str;
  498.                                       {If Escape key pressed, then return the}
  499.                                       {default value.  Otherwise return work}
  500.                                       {string}
  501. end; { EditString }
  502.  
  503. begin
  504.    GS_KeyI_Esc := false;
  505.    GS_KeyI_Fuc := false;
  506.    GS_KeyI_Ins := false;
  507.    GS_KeyI_Ret := false;
  508.    GS_KeyI_Chr := #0;                 {Initialize character to null}
  509. end.
  510.  
  511.